package model.analyzer;

import japa.parser.JavaParser;
import japa.parser.ParseException;
import japa.parser.ast.CompilationUnit;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashSet;

import DAO.ICodeDAO;
import DAO.mysql.MySQLDAO;

public class Main {
//test construct java ast
	private static MySQLDAO sqlDAO = new MySQLDAO();
	private static HashSet<String> parsed;
	private static RandomAccessFile persistData;// = new RandomAccessFile("./record/analyzed", "rw");

	public static void parseDir(File directory, int level) throws ParseException {
		//System.out.println(directory.getName());
		File[] children = directory.listFiles();
		if(directory.isFile() && directory.getPath().endsWith(".java")) {

			System.out.println("parsing " + directory);
			
			try {
				CompilationUnit root = JavaParser.parse(directory);
				
				ICodeDAO dao = sqlDAO.getCodeDAO();
				IdentifyVisitor dumpVisitor = new IdentifyVisitor(dao);
				root.accept(dumpVisitor, null);
				
				FileInputStream in = new FileInputStream(directory);
				BufferedInputStream ins = new BufferedInputStream(in);
				byte[] buffer = new byte[1024];
				String temp = "";
				int readLen = 0;
				while((readLen = ins.read(buffer)) > 0) {
					String inStr = new String(buffer, 0, readLen);
					temp += inStr;
				}
				dumpVisitor.getSelfData().setSourceCode(temp);
				
				dao.saveDeclaredClass(dumpVisitor.getSelfData());
				
				System.gc();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (Throwable e) {
				e.printStackTrace();
				return;
			}
			
//			System.out.println(dumpVisitor.getClassPath());
//			System.out.println(dumpVisitor.getSource());
			return;
		}
		if(children != null) {
			for(File f : children) {
				if(f.isDirectory() && level == 0) {
					if(parsed.contains(f.getPath())) {
						continue;
					}
				}
				parseDir(f, level + 1);
				if(f.isDirectory() && level == 0) {
					parsed.add(f.getPath());
					try {
						persistData.seek(persistData.length());
						persistData.writeUTF(f.getPath());
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
			}
		}
	}
	
//	public static void saveParsed() {
//		File f = new File("./record/parsed.dat");
//		if(!f.exists()) {
//			try {
//				f.createNewFile();
//			} catch (IOException e) {
//				e.printStackTrace();
//			}
//		}
//		try {
//			ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(f));
//			os.writeObject(parsed);
//			os.close();
//		} catch (FileNotFoundException e) {
//			e.printStackTrace();
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
//	}
	
	public static void main(String[] args) throws ParseException, FileNotFoundException, IOException, ClassNotFoundException {
		File f = new File("./record/parsed.dat");
		if(!f.exists()) {
			f.createNewFile();
		}
		persistData = new RandomAccessFile("./record/analyzed", "rw");
		parsed = new HashSet<String>();
		while(true) {
			try {
				String data = persistData.readUTF();
				parsed.add(data);
			} catch(Throwable e) {
				break;
			}
		}

		parseDir(new File("D:/cvs/"), 0);
	}
}
